var types = ["string", "integer", "number", "array", "boolean", "object"]
var keys = ["type", "nullable", "format", "description", "items", "$ref", "readOnly", "additionalProperties", "default", "deprecated", "writeOnly"]

const formatModelsObject = function (properties, $ref) {
    if (!properties && $ref) {
        return $ref;
    }
    var itemArray = [];
    for (const key in properties) {
        const keyItem = properties[key];
        var _obj = formatBase(keyItem, key);
        if (_obj.type == 'array') {
            _obj.type = 'array';
            _obj.itemArray = formatModelsArray(keyItem.items);
        };
        if (_obj.type == 'object') {
            _obj.type = 'object';
            if (keyItem.additionalProperties) {
                _obj.itemArray = [formatDict(keyItem.additionalProperties)];
            } else {
                _obj.itemArray = formatModelsObject(keyItem.properties, keyItem.$ref);
            };
        };
        itemArray.push(_obj);
    };
    return itemArray;
};
const formatDict = function (additionalProperties) {
    var model = formatBase(additionalProperties, '\'<*>\'');
    if (additionalProperties.type == 'object' || !additionalProperties.type) {
        model.itemArray = formatModelsObject(additionalProperties.properties, additionalProperties.$ref);
    } else if (additionalProperties.type == 'array') {
        model.itemArray = formatModelsArray(additionalProperties.items)
    }
    return model;
}
const formatModelsArray = function (ModelsArray) {
    if (ModelsArray.type == 'object') {
        return formatModelsObject(ModelsArray.properties, ModelsArray.$ref);
    } else if (ModelsArray.type == 'array') {
        return formatModelsArray(ModelsArray.items)
    } else if (ModelsArray.$ref) {
        return ModelsArray.$ref;
    } else {
        return formatBase(ModelsArray);
    }
};
const formatBase = function (ModelsSchemas, key) {
    var model = {};
    model.name = ModelsSchemas.description || model.key;
    model.key = key;
    model.type = ModelsSchemas.type || 'object';
    model.checked = !ModelsSchemas.nullable;
    model.itemArray = [];
    ModelsSchemas.enum && (model.enum = ModelsSchemas.enum);
    ModelsSchemas.format && (model.format = ModelsSchemas.format);
    ModelsSchemas.readOnly && (model.readOnly = ModelsSchemas.readOnly);
    ModelsSchemas.default && (model.default = ModelsSchemas.default);
    ModelsSchemas.writeOnly && (model.writeOnly = ModelsSchemas.writeOnly);
    return model;
};
const formatModels = function (ModelsSchemas, key) {
    var model = formatBase(ModelsSchemas, key)
    if (ModelsSchemas.type == 'object' || !ModelsSchemas.type) {
        model.itemArray = formatModelsObject(ModelsSchemas.properties, ModelsSchemas.$ref);
    } else if (ModelsSchemas.type == 'array') {
        model.itemArray = formatModelsArray(ModelsSchemas.items)
    }
    return model;
}


const renderAnnotation = (item, key) => ' // ' + (item.annotate || item.name || '') + (key ? ' ' + key : '') + ' (' + (item.format || item.type) + ') ' + (item.checked ? '必填' : '') + (item.enum ? ' 备选值 ：' + JSON.stringify(item.enum) : '') + '\n';
const formatArrayString = function (Schemas, model) {
    var _array = [];
    _array.push('[' + renderAnnotation(Schemas));
    var _model = Schemas;
    if (typeof Schemas.itemArray == 'string') {
        if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && text.test(Schemas.itemArray)) {
            var _key = Schemas.itemArray.replace('List<', '').replace('>', '');
            model[_key] && (_model = model[_key]);
        } else if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && model[Schemas.itemArray]) {
            _model = model[Schemas.itemArray];
        };
    };
    if (_model.type == 'object') {
        if (_model.itemArray) {
            for (let i = 0; i < _model.itemArray.length; i++) {
                const element = _model.itemArray[i];
                if (element.itemArray == Schemas.itemArray) {
                    element.itemArray = [];
                }
            }
        }
        _array.push(formatObjectString(_model, model));
    } else if (_model.type == 'array' && _model.itemArray.length) {
        _array.push(formatArrayString(_model.itemArray, model));
    } else if (_model.type == 'array' && _model.itemArray.length == 0) {
        _array.push('');
    } else {
        for (let i = 0; i < _model.itemArray.length; i++) {
            let element = _model.itemArray[i];
            _array.push('\'\'' + renderAnnotation(element));
            if (i != _model.itemArray.length - 1) {
                _array.push(',\n')
            };
        }
    };
    _array.push(']\n');
    return _array.join('');
}
var text = /^List\<.*\>$/
const formatObjectString = function (Schemas, model) {
    var _array = [];
    if (typeof Schemas.itemArray == 'string') {
        // console.log(model);
        // 验证这是一个数组类型
        if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && text.test(Schemas.itemArray)) {
            var _key = Schemas.itemArray.replace('List<', '').replace('>', '');
            model[_key] && (Schemas = model[_key]);
        } else if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && model[Schemas.itemArray]) {
            Schemas = model[Schemas.itemArray];
        };
    };
    if (Schemas.type != 'array' && Schemas.type != 'object') {
        _array.push('\'\'' + renderAnnotation(Schemas));
    } else {
        _array.push('{' + renderAnnotation(Schemas, Schemas.key));
        for (let i = 0; i < Schemas.itemArray.length; i++) {
            const element = Schemas.itemArray[i];
            if (element.type == 'object') {
                _array.push(element.key + ':' + formatObjectString(element, model));
                if (i != Schemas.itemArray.length - 1) {
                    _array.push(',\n')
                };
            } else if (element.type == 'array') {
                _array.push(element.key + ':' + formatArrayString(element, model));
                if (i != Schemas.itemArray.length - 1) {
                    _array.push(',\n')
                };
            } else {
                _array.push(element.key + ': \'\' ,' + renderAnnotation(element));
            }
        }
        _array.push('}\n');
    }
    return _array.join('');
}
const formatString = function (Schemas, model) {
    if (Schemas.type == 'array') {
        return formatArrayString(Schemas, model);
    } else if (Schemas.type == 'object') {
        return formatObjectString(Schemas, model);
    } else {
        return '\'\'' + renderAnnotation(Schemas);
    }
};



const formatResponseArrayString = function (value, Schemas, model) {
    var _array = [];
    _array.push('[' + renderAnnotation(Schemas));
    if (typeof Schemas.itemArray == 'string') {
        if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && text.test(Schemas.itemArray)) {
            var _key = Schemas.itemArray.replace('List<', '').replace('>', '');
            Schemas[_key] && (Schemas = model[_key]);
        } else if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && model[Schemas.itemArray]) {
            Schemas = model[Schemas.itemArray];
        };
    };

    for (let i = 0; i < value.length; i++) {
        const _valueItem = value[i];
        if (Schemas.type == 'object') {
            _array.push(formatResponseObjectString(_valueItem, Schemas, model));
            if (i != value.length - 1) {
                _array.push(',\n')
            };
        } else if (Schemas.type == 'array') {
            _array.push(formatResponseArrayString(_valueItem, Schemas.itemArray, model));
            if (i != value.length - 1) {
                _array.push(',\n')
            };
        } else {
            var $value = '';
            if (_Schemas.type == 'string') {
                $value = '\'' + _valueItem + '\'';
            } else {
                $value = _valueItem.toString();
            };
            _array.push('\'' + $value + '\'' + renderAnnotation(element));
        }
    }
    _array.push(']\n');
    return _array.join('');
}
const formatResponseObjectString = function (value, Schemas, model) {
    var _array = [];
    if (typeof Schemas.itemArray == 'string') {
        if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && text.test(Schemas.itemArray)) {
            var _key = Schemas.itemArray.replace('List<', '').replace('>', '');
            model[_key] && (Schemas = model[_key]);
        } else if (Schemas.itemArray.indexOf('#/components/schemas/') != -1 && model[Schemas.itemArray]) {
            Schemas = model[Schemas.itemArray];
        };
    };

    var _length = Object.keys(value).length;
    var keyIndex = 0;
    if (Schemas.type != 'array' && Schemas.type != 'object') {
        _array.push('\'\'' + renderAnnotation(Schemas));
    } else {
        _array.push('{' + renderAnnotation(Schemas, Schemas.key));
        var _SchemasMapping = {};
        Schemas.itemArray.forEach(ele => {
            _SchemasMapping[ele.key] = ele;
        });
        for (const key in value) {
            const _value = value[key];
            const _Schemas = _SchemasMapping[key];
            keyIndex++;
            if (!_Schemas) {
                var $value = '';
                _array.push(key + ': \'' + _value + '\' ,');
            } else if (_Schemas.type == 'object') {
                _array.push(key + ':' + formatResponseObjectString(_value, _Schemas, model));
                if (keyIndex != _length - 1) {
                    _array.push(',\n')
                };
            } else if (_Schemas.type == 'array') {
                _array.push(key + ':' + formatResponseArrayString(_value, _Schemas, model));
                if (keyIndex != _length - 1) {
                    _array.push(',\n')
                };
            } else {
                var $value = '';
                if (_Schemas.type == 'string') {
                    $value = '\'' + _value + '\'';
                } else {
                    $value = _value.toString();
                }
                _array.push((_Schemas.key == '<*>' ? key : _Schemas.key) + ': ' + $value + ' ,' + renderAnnotation(_Schemas));
            }
        }
        _array.push('}\n');
    }
    return _array.join('');
}


const formatResponse = function (value, Schemas, model) {
    if (Schemas.type == 'array') {
        return formatResponseArrayString(value, Schemas, model);
    } else if (Schemas.type == 'object') {
        return formatResponseObjectString(value, Schemas, model);
    } else {
        if (Schemas.type == 'string') {
            return '\'' + value + '\'' + renderAnnotation(Schemas)
        } else {
            return value.toString() + renderAnnotation(Schemas);
        }
    }
};

export default {
    String: formatString,
    Models: formatModels,
    Response: formatResponse,
}



